#include "pointToolTip.h"

void pointToolTip::setStream(QTextStream &stream, gObject *object, gTypeGo *go){

	stream << "<i>" << object->getName().c_str() << "</i> ";
	stream << "<font color=" COLOR_PARAMS ">";
	if(object->getSpindle() != -1)	
		stream << " S" << object->getSpindle();
	if(object->getFeed() > 0)
		stream << " F" << object->getFeed();
	stream << "</font>";
	stream << "</p><font color=" COLOR_TAG "> G";
	stream << qSetPadChar('0') << qSetFieldWidth(2) << go->getTypeValue();
	stream << "</font>";
	stream << "<table>";
	stream << "<tr>";
	stream << "<td>";
	stream << "<font color=" COLOR_COORDINATES ">" << " X" << "</font>";
	stream << fixed << "<font color=" COLOR_VALUE ">" << qSetRealNumberPrecision(FLOAT_PRECISION) << "</font>" << (*go)[0];
	stream << "</td>";
	stream << "<td>";
	stream << "<font color=" COLOR_COORDINATES ">" << " Y" << "</font>";
	stream << fixed << "<font color=" COLOR_VALUE ">" << qSetRealNumberPrecision(FLOAT_PRECISION) << "</font>" << (*go)[1];
	stream << "</td>";	
	stream << "<td>";
	stream << "<font color=" COLOR_COORDINATES ">" << " Z" << "</font>";
	stream << fixed << "<font color=" COLOR_VALUE ">" << qSetRealNumberPrecision(FLOAT_PRECISION) << "</font>" << (*go)[2];
	stream << "</td>";
	stream << "</tr>";
	if(go->getTypeValue() == TYPE_ARC_CLOCK || go->getTypeValue() == TYPE_ARC_COUNTER){	
		stream << "<tr>";
		stream << "<td>";
		stream << "<font color=" COLOR_MIDDLE ">" << " I" << "</font>";
		stream  << fixed << "<font color=" COLOR_VALUE ">" << qSetRealNumberPrecision(FLOAT_PRECISION) << "</font>" << (*go)[3];
		stream << "</td>";
		stream << "<td>";
		stream << "<font color=" COLOR_MIDDLE ">" << " J" << "</font>";
		stream << fixed << "<font color=" COLOR_VALUE ">" << qSetRealNumberPrecision(FLOAT_PRECISION) << "</font>" << (*go)[4];
		stream << "</td>";
		stream << "</tr>";
	}
	stream << "</table>";
	
}

void pointToolTip::showGInformation(
	const QPoint &point, 
	gObject *object,
	gTypeGo *go,
	QWidget *parent
	){
		
	QString str;
	QTextStream stream(&str);

	setStream(stream, object, go);
	showText(point, str, parent);

}

void pointToolTip::showGInformations(const QPoint &point, gObjectContainer *container, QWidget *parent){

	gObjectContainer::iterator iter = container->begin();
	gObject::iterator objectIter;
	QString str;
	QTextStream stream(&str);
	
	for(; iter != container->end(); iter++){
		objectIter = (*iter)->begin();
		for(; objectIter != (*iter)->end(); objectIter++){
			//if((*iter)->begin() != objectIter)
				stream << "<hr width=\"100%\">";
			setStream(stream, *iter, dynamic_cast<gTypeGo *>(*objectIter));
		}
	}
	showText(point, str, parent);

}

void pointToolTip::showDistance(
	const QPoint &point, 
	const QPointF &clicked, 
	const QPointF &active,
	const QPointF &z,
	QWidget *parent
	){

	float dxyz, dxy, dx, dy, dz;
	
	dx = active.x() - clicked.x();
	dy = active.y() - clicked.y();
	dz = z.y() - z.x();
	dxy = sqrt(dx * dx + dy * dy);
	dxyz = sqrt(dx * dx + dy * dy + dz * dz);
	QString str;
	QTextStream stream(&str);
	stream << fixed << qSetRealNumberPrecision(FLOAT_PRECISION) << "<i>dx = </i>" << dx << "<br>";
	stream << fixed << qSetRealNumberPrecision(FLOAT_PRECISION) << "<i>dy = </i>" << dy << "<br>";
	stream << fixed << qSetRealNumberPrecision(FLOAT_PRECISION) << "<i>dz = </i>" << dz << "<br>";
	stream << fixed << qSetRealNumberPrecision(FLOAT_PRECISION)<< "<i>|x, y| = </i>" << dxy << "<br>";
	stream << fixed << qSetRealNumberPrecision(FLOAT_PRECISION)<< "<i>|x, y, z| = </i>" << dxyz;
	showText(point, str, parent);

}

listToolTip::listToolTip(QWidget *parent): QListView(parent){
	
	model = NULL;
	modelAdd = NULL;
	shift = false;
	delegate = new HTMLDelegate;
	setItemDelegate(delegate);
	setFocusPolicy(Qt::StrongFocus);

}

listToolTip::~listToolTip(){

	delete model;
	delete modelAdd;

}

void listToolTip::mouseDoubleClickEvent(QMouseEvent *event){

	additional add(modelAdd->at(currentIndex ().row()));

	if(event->modifiers() == Qt::ShiftModifier)
		emit doubleClicked(add.i, add.go);
	else
		emit clicked(add.i, add.go);
	
}

void listToolTip::appendGTypeGo(gObject &object, gTypeGo &go, QStringList &list) const{
	
	QString string;
	QTextStream stream(&string);
	
	pointToolTip::setStream(stream, &object, &go);
	stream.flush();
	list.append(string);

}

void listToolTip::setObject(gObjectContainer *container, gObject *object, gObject *objectPointer){

	delete model;
	delete modelAdd;
	
	gObject::iterator iter = object->begin();
	QStringList list;
	additional add;
	gTypeGo *go;
	
	model = new QStringListModel;
	modelAdd = new QList<additional>;
	add.i = container->getIndexByObject(objectPointer);
	for(; iter != object->end(); iter++){
		go = dynamic_cast<gTypeGo *>(*iter);
		appendGTypeGo(*object, *go, list);
		add.go = go;
		modelAdd->append(add);
	}
	model->setStringList(list);
	setModel(model);

}

void listToolTip::setContainer(gObjectContainer *container){

	delete model;
	delete modelAdd;
	
	gObjectContainer::iterator iter = container->begin();
	gObject::iterator iterObject;
	QStringList list;
	additional add;
	gObject *object;
	gTypeGo *go;
	
	model = new QStringListModel;
	modelAdd = new QList<additional>;
	for(; iter != container->end(); iter++){
		object = *iter;
		iterObject = object->begin();
		for(; iterObject != object->end(); iterObject++){
			go = dynamic_cast<gTypeGo *>(*iterObject);
			appendGTypeGo(*object, *go, list);
			add.i = iter - container->begin();
			add.go = go;
			modelAdd->append(add);
		}
	}
	model->setStringList(list);
	setModel(model);

}

void listToolTip::show(const QPoint &point){

	move(point.x(), point.y());
	setVisible(true);

}

int listToolTip::gTypeCount() const{

	return modelAdd->size();

}

void HTMLDelegate::paint(
	QPainter *painter, 
	const QStyleOptionViewItem &option, 
	const QModelIndex &index
	) const{
	
	QStyleOptionViewItemV4 options = option;
	initStyleOption(&options, index);

	painter->save();

	QTextDocument doc;
	doc.setHtml(options.text);

	if(index.row() % 2)
		painter->fillRect(option.rect, QBrush(QColor(Qt::lightGray)));

	options.text = "";
	options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);
	
	painter->translate(options.rect.left(), options.rect.top());
	QRect clip(0, 0, options.rect.width(), options.rect.height());
	doc.drawContents(painter, clip);

	painter->restore();
	
}

QSize HTMLDelegate::sizeHint (
	const QStyleOptionViewItem &option,
	const QModelIndex &index
	) const{
	
	QStyleOptionViewItemV4 options = option;
	options.backgroundBrush = QBrush(QColor(255, 0, 0));
	initStyleOption(&options, index);

	QTextDocument doc;
	doc.setHtml(options.text);
	doc.setTextWidth(options.rect.width());
	return QSize(doc.idealWidth(), doc.size().height());
	
}

listToolTipDialog::listToolTipDialog(QWidget *parent): QDialog(parent){

	object = NULL; 
	go = NULL;
	state = NONE;
	listTip = new listToolTip;
	vLayout = new QVBoxLayout;
	vLayout->setContentsMargins(0, 0, 0, 0);
	vLayout->addWidget(listTip);
	setLayout(vLayout);
	setWindowFlags(Qt::Popup);
	connect(listTip, SIGNAL(clicked(int, gTypeGo *)),
		this, SLOT(clicked(int, gTypeGo *)));
	connect(listTip, SIGNAL(doubleClicked(int, gTypeGo *)),
		this, SLOT(doubleClicked(int, gTypeGo *)));

}

void listToolTipDialog::doubleClicked(int i, gTypeGo *g){

	state = DOUBLECLICKED;
	object = i;
	go = g;
	accept();

}

void listToolTipDialog::clicked(int i, gTypeGo *g){

	state = CLICKED;
	object = i;
	go = g;
	accept();

}
